import hypermedia.video.*;
import processing.serial.*;

OpenCV opencv;
int MAX_BRIGHTNESS = 255;
int FONT_SIZE = 20;
Serial myPort;

void setup() 
{
  colorMode(HSB);
  float factor = 1;
  int wwidth = (int)(320 * factor);
  int wheight = (int)(240 * factor);
  size(wwidth, wheight);

  opencv = new OpenCV(this);
  opencv.capture(width, height);
  PFont font = createFont("FFScala", FONT_SIZE);
  textFont(font);
  
  println(Serial.list());
  //myPort = new Serial(this, Serial.list()[0], 9600);
  
  smooth();
}

void draw() 
{
  opencv.read();

  PImage shot = opencv.image();
  //FalseColor(shot);
  image( shot, 0, 0 );
  generateHistogramAndWave(opencv.image());
  
  int distance = 0;//getValue();

  text(distance, width - width * .15, height - FONT_SIZE / 2);
}

int getValue() 
{
  int value = -1;
//  print(myPort.available() + "\n");
  while (myPort.available() >= 3) {
    if (myPort.read() == 0xff) {
      value = (myPort.read() << 8) | (myPort.read());
    }
  }
  return value;
}


void generateHistogramAndWave(PImage img)
{
  int hwidth, hheight;
  hwidth = hheight = img.height/4;
  int [] histogramValues = new int[hwidth];
  int maxSum =  img.height * MAX_BRIGHTNESS;

  PGraphics histogram = createGraphics(hwidth, hheight, P3D);
  PGraphics waveform = createGraphics(hwidth, hheight, P3D);

  histogram.beginDraw();
  waveform.beginDraw();

  histogram.background(255);
  waveform.background(255);

  histogram.stroke(0);
  waveform.stroke(0);

  for(int w = 0; w < img.width; w++)
  {
    float brightSum = 0;
    float brightLocal = 0;
    int xpos = hwidth * w / img.width;
    int ypos = 0;

    for(int h = 0; h < img.height; h++)
    {
      brightLocal = (int)brightness(img.pixels[h * img.width + w]);
      brightSum += brightLocal;
      ypos = (int)(brightLocal * hheight / MAX_BRIGHTNESS);

      waveform.point(xpos, hwidth - ypos);
    }

    histogramValues[xpos] = brightSum != 0 ? (int)(brightSum * hheight / maxSum) : 0;
  }

  for(int i = 0; i < hwidth; i++)
  {
    for(int j = i + 1; j < hwidth; j++)
    {
      if(histogramValues[i] < histogramValues[j])
      {
        int temp = histogramValues[i];
        histogramValues[i] = histogramValues[j];
        histogramValues[j] = temp;
      }      
    }
  }

  for(int x = 0; x < hwidth; x++)
  {
    //histogram.line(x, hwidth, x, hwidth - histogramValues[x]);
    histogram.point(x, hwidth - histogramValues[x]);
  }

  histogram.endDraw();
  waveform.endDraw();

  image(histogram, 0, 0);
  image(waveform, img.width - hwidth, 0);
}

void FalseColor(PImage img)
{
  int dimension = img.width * img.height;
  color pixel;

  for(int i = 0; i < dimension; i++)
  {
    pixel = img.pixels[i];
    float bright = brightness(pixel);
    int brightInt = (int)bright / (255 / 9);
    int level = brightInt * (255 / 9);
    color newPixel = color(level, level, level);
    img.pixels[i] = newPixel;
  }

  image( img, 0, 0 );
}
